import os
import sys
import yaml
import uvicorn
import logging
import requests
import time
from loguru import logger

# 添加项目根目录到Python路径
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

# 加载配置
def load_config():
    """加载配置文件"""
    config_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'configs', 'config.yaml')
    if not os.path.exists(config_path):
        logger.error(f"配置文件不存在: {config_path}")
        sys.exit(1)
    
    with open(config_path, 'r', encoding='utf-8') as f:
        config = yaml.safe_load(f)
    
    return config

# 初始化日志
def setup_logging(config):
    """设置日志配置"""
    log_config = config.get('logging', {})
    log_file = log_config.get('file', 'app.log')
    log_level = log_config.get('level', 'INFO')
    log_rotation = log_config.get('rotation', '10 MB')
    log_retention = log_config.get('retention', '7 days')
    
    # 配置loguru
    logger.remove()  # 移除默认的handler
    logger.add(
        sys.stdout,
        level=log_level,
        format="<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> | <level>{level: <8}</level> | <cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - <level>{message}</level>",
        backtrace=True,
        diagnose=True
    )
    
    logger.add(
        log_file,
        rotation=log_rotation,
        retention=log_retention,
        level=log_level,
        format="{time:YYYY-MM-DD HH:mm:ss.SSS} | {level: <8} | {name}:{function}:{line} - {message}",
        backtrace=True,
        diagnose=True
    )
    
    # 禁用uvicorn的访问日志（如果需要）
    if not log_config.get('uvicorn_access_log', True):
        uvicorn_logger = logging.getLogger("uvicorn.access")
        uvicorn_logger.disabled = True

# 初始化数据库
def init_database(config):
    """初始化数据库连接"""
    from backend.database.db import db_manager
    
    try:
        # DatabaseManager是单例模式，导入时已自动初始化
        logger.info("数据库初始化成功")
        return True
    except Exception as e:
        logger.error(f"数据库初始化失败: {str(e)}")
        return False

# 初始化模型
def init_model(config):
    """初始化模型"""
    from backend.models.model_loader import model_manager
    
    try:
        # ModelManager是单例模式，导入时已自动初始化
        logger.info("模型初始化成功")
        return True
    except Exception as e:
        logger.error(f"模型初始化失败: {str(e)}")
        return False

# 初始化RAG
def init_rag(config):
    """初始化RAG"""
    from backend.rag.retriever import rag_manager
    
    try:
        # RAGManager使用单例模式，在导入时自动初始化
        # 这里只需要确保rag_config正确
        rag_manager.rag_config = config['rag']
        logger.info("RAG初始化成功")
        return True
    except Exception as e:
        logger.error(f"RAG初始化失败: {str(e)}")
        return False

# 初始化工具调用
def init_tool_caller(config):
    """初始化工具调用"""
    from backend.tools.tool_caller import tool_caller
    
    try:
        # ToolCaller使用单例模式，在导入时自动初始化
        # 这里只需要确保tools_config正确
        tool_caller.tools_config = config['tools']
        logger.info("工具调用初始化成功")
        return True
    except Exception as e:
        logger.error(f"工具调用初始化失败: {str(e)}")
        return False

# 初始化学习功能
def init_learning(config):
    """初始化学习功能"""
    from backend.learning.trainer import learning_manager
    
    try:
        # LearningManager使用单例模式，在导入时自动初始化
        # 这里只需要确保learning_config正确
        learning_manager.learning_config = config['learning']
        logger.info("学习功能初始化成功")
        return True
    except Exception as e:
        logger.error(f"学习功能初始化失败: {str(e)}")
        return False

# 健康检查
def check_health(config):
    """检查后端服务健康状态"""
    api_config = config['api']
    base_url = f"http://{api_config['host']}:{api_config['port']}"
    
    # 检查健康接口
    try:
        health_url = f"{base_url}/v1/health"
        health_response = requests.get(health_url, timeout=5)
        if health_response.status_code == 200:
            logger.info("✅ 健康检查通过")
        else:
            logger.error(f"❌ 健康检查失败: HTTP {health_response.status_code}")
            return False
    except Exception as e:
        logger.error(f"❌ 健康检查失败: {str(e)}")
        return False
    
    # 检查会话接口
    try:
        sessions_url = f"{base_url}/v1/sessions"
        sessions_response = requests.get(sessions_url, timeout=5)
        if sessions_response.status_code == 200:
            logger.info("✅ 会话接口检查通过")
        else:
            logger.error(f"❌ 会话接口检查失败: HTTP {sessions_response.status_code}")
            return False
    except Exception as e:
        logger.error(f"❌ 会话接口检查失败: {str(e)}")
        return False
    
    return True

# Ollama检查
def check_ollama():
    """检查Ollama服务状态"""
    ollama_url = os.getenv("OLLAMA_BASE_URL", os.getenv("OLLAMA_BASE", "http://127.0.0.1:11434"))
    try:
        tags_url = f"{ollama_url}/api/tags"
        response = requests.get(tags_url, timeout=5)
        if response.status_code == 200:
            models = response.json().get('models', [])
            if models:
                logger.info(f"✅ Ollama服务正常，已安装 {len(models)} 个模型")
                return True
            else:
                logger.warning("⚠️ Ollama服务正常，但未安装任何模型")
                return True  # Ollama服务运行但无模型，仍然返回True
        else:
            logger.error(f"❌ Ollama服务检查失败: HTTP {response.status_code}")
            return False
    except Exception as e:
        logger.error(f"❌ Ollama服务不可达: {str(e)}")
        logger.error("请确保Ollama服务已启动且运行在正确的地址")
        logger.error(f"建议运行: ollama pull {os.getenv('OLLAMA_MODEL', 'qwen2.5:7b')}")
        return False

# 启动FastAPI服务器
def start_server(config):
    """启动FastAPI服务器"""
    api_config = config['api']
    
    logger.info(f"启动FastAPI服务器: {api_config['host']}:{api_config['port']}")
    logger.info(f"文档访问地址: http://{api_config['host']}:{api_config['port']}/api/docs")
    
    # 启动服务器
    server_process = uvicorn.run(
        "backend.api.main:app",
        host=api_config['host'],
        port=api_config['port'],
        workers=api_config['workers'],
        reload=api_config['debug'],
        log_level="info",  # 直接使用默认的日志级别
        lifespan="on"  # 确保生命周期事件正确处理
    )
    
    return server_process

# 主函数
def main():
    """主函数，启动AI助手系统"""
    # 加载配置
    logger.info("===== 启动AI助手系统 ====")
    config = load_config()
    
    # 设置日志
    setup_logging(config)
    
    # 初始化数据库
    try:
        if not config.get('startup', {}).get('skip_database', True):
            init_database(config)
        else:
            logger.info("跳过数据库初始化")
    except Exception as e:
        logger.error(f"数据库初始化失败: {str(e)}")
        # 即使数据库初始化失败，也继续尝试启动其他组件
        
    # 初始化模型
    try:
        if not config.get('startup', {}).get('skip_model_preload', True):
            init_model(config)
        else:
            logger.info("跳过模型预加载，将在首次请求时加载")
    except Exception as e:
        logger.error(f"模型初始化失败: {str(e)}")
    
    # 初始化RAG
    try:
        if not config.get('startup', {}).get('skip_rag', True) and 'rag' in config and config['rag'].get('enabled', False):
            init_rag(config)
        else:
            logger.info("跳过RAG初始化")
    except Exception as e:
        logger.error(f"RAG初始化失败: {str(e)}")
    
    # 初始化工具调用
    try:
        if not config.get('startup', {}).get('skip_tools', True) and 'tools' in config and config['tools'].get('enabled', False):
            init_tool_caller(config)
        else:
            logger.info("跳过工具调用初始化")
    except Exception as e:
        logger.error(f"工具调用初始化失败: {str(e)}")
    
    # 初始化学习功能
    try:
        if not config.get('startup', {}).get('skip_learning', True) and 'learning' in config and config['learning'].get('enabled', False):
            init_learning(config)
        else:
            logger.info("跳过学习功能初始化")
    except Exception as e:
        logger.error(f"学习功能初始化失败: {str(e)}")
    
    # 启动服务器
    try:
        # 先检查Ollama服务
        logger.info("===== 开始服务检查 =====")
        ollama_healthy = check_ollama()
        
        # 启动服务器
        server_process = start_server(config)
        
        # 服务器启动后等待片刻再进行健康检查
        logger.info("等待服务器完全启动...")
        time.sleep(5)  # 等待5秒让服务器初始化
        
        # 检查后端服务健康状态
        health_check_passed = check_health(config)
        
        # 输出检查结果摘要
        logger.info("===== 服务检查结果 =====")
        if ollama_healthy:
            logger.info("Ollama服务: ✅ 正常")
        else:
            logger.error("Ollama服务: ❌ 异常 - 功能可能受限")
        
        if health_check_passed:
            logger.info("后端服务: ✅ 正常运行")
        else:
            logger.error("后端服务: ❌ 异常 - 请检查日志")
        
        # 返回服务器进程
        return server_process
        
    except Exception as e:
        logger.error(f"服务器启动失败: {str(e)}")
        raise

# 入口点
if __name__ == "__main__":
    main()